package com.wiscamp.ninechapters.tags.adapter.resources;

import com.wiscamp.ninechapters.tags.application.dto.command.*;
import com.wiscamp.ninechapters.tags.application.dto.vo.KnowledgePointRelationVO;
import com.wiscamp.ninechapters.tags.application.dto.vo.KnowledgePointVO;
import com.wiscamp.ninechapters.tags.application.dto.vo.KnowledgeTreePointVO;
import com.wiscamp.ninechapters.tags.application.services.KnowledgePointAppService;
import cube.ddd.adapter.BaseController;
import cube.ddd.adapter.RestResponse;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.aspect.HandleResourceException;
import cube.ddd.utils.ResourceUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.core.Context;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

/**
 * 学科知识点服务端点
 *
 * @author yifeng
 */
@RestController
@RequestMapping("/api/Tags")
@Tag(name = "标签知识点-学科知识点信息")
public class KnowledgePointController extends BaseController {

    private final KnowledgePointAppService knowledgePointAppService;

    public KnowledgePointController(KnowledgePointAppService knowledgePointAppService) {
        this.knowledgePointAppService = knowledgePointAppService;
    }

    //region knowledgePoint

    /**
     * 通过学科知识点编号获取学科知识点
     *
     * @param request
     * @param response
     * @param pointId
     * @return
     */
    @GetMapping("KnowledgePoints/{pointId}")
    @Operation(summary = "通过学科知识点编号获取学科知识点")
    @HandleResourceException
    public RestResponse<KnowledgePointVO> getKnowledgePoint(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                            @PathVariable("pointId") long pointId) {
        return ResourceUtils.getById(request, response, pointId, knowledgePointAppService::getKnowledgePoint);
    }

    /**
     * 通过学科编号获取学科知识点列表
     *
     * @return 学科知识点列表
     */
    @GetMapping("Subjects/{subjectId}/KnowledgePoints")
    @Operation(summary = "通过学科编号获取学科知识点列表")
    @HandleResourceException
    public RestResponse<Collection<KnowledgePointVO>> getKnowledgePointsBySubject(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                  @PathVariable("subjectId") long subjectId) {
        return ResourceUtils.getListById(request, response, subjectId, knowledgePointAppService::getKnowledgePointsBySubject);
    }

    /**
     * 通过学科编号和知识点代码获取学科知识点
     *
     * @param pointCode
     * @return
     */
    @GetMapping("Subjects/{subjectId}/KnowledgePoints/Code/{pointCode}")
    @Operation(summary = "通过学科编号和知识点代码获取学科知识点")
    @HandleResourceException
    public RestResponse<KnowledgePointVO> getKnowledgePointByCode(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                  @PathVariable("subjectId") long subjectId,
                                                                  @PathVariable("pointCode") String pointCode) {
        return ResourceUtils.getByTextAndId(request, response, pointCode, subjectId, knowledgePointAppService::getKnowledgePointByCode);
    }

    /**
     * 通过学科编号和知识点名称获取学科知识点列表
     *
     * @param pointName
     * @return
     */
    @GetMapping("Subjects/{subjectId}/KnowledgePoints/Name/{pointName}")
    @Operation(summary = "通过学科编号和知识点名称获取学科知识点列表")
    @HandleResourceException
    public RestResponse<Collection<KnowledgePointVO>> getKnowledgePointsByName(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                               @PathVariable("subjectId") long subjectId,
                                                                               @PathVariable("pointName") String pointName) {
        return ResourceUtils.getListByTextAndId(request, response, pointName, subjectId, knowledgePointAppService::getKnowledgePointsByName);
    }

    /**
     * 通过学科编号和知识点名称获取学科知识点列表
     *
     * @param name
     * @return
     */
    @GetMapping("Subjects/{subjectId}/KnowledgePoints/Name/Contains/{name}")
    @Operation(summary = "通过学科编号和知识点名称获取学科知识点列表")
    @HandleResourceException
    public RestResponse<Collection<KnowledgePointVO>> getKnowledgePointsByNameContains(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                       @PathVariable("subjectId") long subjectId,
                                                                                       @PathVariable("name") String name) {
        return ResourceUtils.getListByTextAndId(request, response, name, subjectId, knowledgePointAppService::getKnowledgePointsByNameContains);
    }

    @PostMapping("Subjects/{subjectId}/KnowledgePoints/Random/{quantity}")
    @Operation(summary = "获取随机学科知识点")
    @HandleResourceException
    public RestResponse<Collection<KnowledgePointVO>> getRandomKnowledgePoints(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                               @PathVariable("subjectId") long subjectId,
                                                                               @PathVariable("quantity") int quantity) {
        var result = knowledgePointAppService.getRandomKnowledgePoints(subjectId, quantity);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    /**
     * 通过学科知识点编号删除学科知识点
     *
     * @param id
     * @return
     */
    @PutMapping("KnowledgePoints/Actions/Delete")
    @Operation(summary = "通过学科知识点编号删除学科知识点")
    @HandleResourceException
    public RestResponse<Boolean> deleteKnowledgePoint(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                      @RequestBody DeleteCommand command) {
        return ResourceUtils.delete(request, response, command, knowledgePointAppService::deleteKnowledgePoint);
    }

    /**
     * 创建学科知识点
     *
     * @param command
     * @return
     */

    @PostMapping("KnowledgePoints")
    @Operation(summary = "创建学科知识点")
    @HandleResourceException
    public RestResponse<KnowledgePointVO> createKnowledgePoint(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                               @RequestBody CreateKnowledgePointCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, knowledgePointAppService::createKnowledgePoint);
    }

    /**
     * 更新学科知识点
     *
     * @param command
     * @return
     */
    @PutMapping("KnowledgePoints")
    @Operation(summary = "更新学科知识点")
    @HandleResourceException
    public RestResponse<KnowledgePointVO> updateKnowledgePoint(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                               @RequestBody UpdateKnowledgePointCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, knowledgePointAppService::updateKnowledgePoint);
    }

    //endregion


    //region knowledgeTree

    @GetMapping("Subjects/{subjectId}/KnowledgePoints/Tree")
    @Operation(summary = "获取学科知识点树")
    @HandleResourceException
    public RestResponse<Collection<KnowledgeTreePointVO>> getKnowledgeTreePointsBySubject(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                          @PathVariable("subjectId") long subjectId) {
        var treePoints = knowledgePointAppService.getKnowledgeTreePointsBySubject(subjectId);
        return ResourceUtils.getOkResponse(request, response, treePoints);
    }

    @GetMapping("Subjects/{subjectId}/KnowledgePoints/Tree/{parentId}")
    @Operation(summary = "通过父级知识点获取所有子级知识点树")
    @HandleResourceException
    public RestResponse<Collection<KnowledgeTreePointVO>> getKnowledgeTreePointsByParent(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                         @PathVariable("subjectId") long subjectId,
                                                                                         @PathVariable("parentId") long parentId) {
        var result = knowledgePointAppService.getKnowledgeTreePointsByParent(subjectId, parentId);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    /**
     * 移动学科知识点
     *
     * @param subjectId
     * @param point
     * @return
     */
    @PostMapping("KnowledgePoints/Tree/Actions/Move")
    @Operation(summary = "移动学科知识点")
    @HandleResourceException
    public RestResponse<Boolean> moveKnowledgeTreePoint(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                        MoveKnowledgeTreePointCommand command) {
        var result = knowledgePointAppService.moveKnowledgeTreePoint(command);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    //endregion


    //region knowledgePoint relation

    /**
     * 创建学科知识点关联
     *
     * @param command
     * @return
     */
    @PostMapping("KnowledgePoints/Relations")
    @Operation(summary = "创建学科知识点关联")
    @HandleResourceException
    public RestResponse<KnowledgePointRelationVO> createKnowledgePointRelation(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                               @RequestBody CreateKnowledgePointRelationCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, knowledgePointAppService::createKnowledgePointRelation);
    }

    /**
     * 更新学科知识点关联
     *
     * @param command
     * @return
     */
    @PutMapping("KnowledgePoints/Relations")
    @Operation(summary = "更新学科知识点关联")
    @HandleResourceException
    public RestResponse<KnowledgePointRelationVO> updateKnowledgePointRelation(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                               @RequestBody UpdateKnowledgePointRelationCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, knowledgePointAppService::updateKnowledgePointRelation);
    }

    /**
     * 通过关联编号删除学科知识点关联
     *
     * @param id
     * @return
     */
    @DeleteMapping("KnowledgePoints/Relations")
    @Operation(summary = "通过关联编号删除学科知识点关联")
    @HandleResourceException
    public RestResponse<Boolean> deleteKnowledgePointRelation(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                              @RequestBody DeleteCommand command) {
        return ResourceUtils.delete(request, response, command, knowledgePointAppService::deleteKnowledgePointRelation);
    }

    @DeleteMapping("KnowledgePoints/Relations/{id}")
    @Operation(summary = "通过关联编号删除学科知识点关联")
    @HandleResourceException
    public RestResponse<Boolean> deleteKnowledgePointRelationById(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                              @PathVariable("id") long id) {
        var command = new DeleteCommand();
        command.setId(id);
        return ResourceUtils.delete(request, response, command, knowledgePointAppService::deleteKnowledgePointRelation);
    }

    /**
     * 通过关联编号获取学科知识点关联
     *
     * @param request
     * @param response
     * @param id
     * @return
     */
    @GetMapping("KnowledgePoints/Relations/{id}")
    @Operation(summary = "通过关联编号获取学科知识点关联")
    @HandleResourceException
    public RestResponse<KnowledgePointRelationVO> getKnowledgePointRelation(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                            @PathVariable("id") long id) {
        return ResourceUtils.getById(request, response, id, knowledgePointAppService::getKnowledgePointRelation);
    }

    /**
     * 通过源知识点和目标知识点编号获取学科知识点关联
     *
     * @param request
     * @param response
     * @param sourceId
     * @param targetId
     * @return
     */
    @GetMapping("KnowledgePoints/Relations/Binds/{sourceId}")
    @Operation(summary = "通过源知识点编号获取学科知识点关联")
    @HandleResourceException
    public RestResponse<Collection<KnowledgePointRelationVO>> getKnowledgePointRelationsBySource(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                                 @PathVariable("sourceId") long sourceId) {
        return ResourceUtils.getListById(request, response, sourceId, knowledgePointAppService::getKnowledgePointRelationsBySource);
    }

    @GetMapping("KnowledgePoints/Relations/Binds/{sourceId}/NonAggregation")
    @Operation(summary = "通过源知识编号获取非组成关系")
    @HandleResourceException
    public RestResponse<Collection<KnowledgePointRelationVO>> getNonAggregationRelationsByPoint(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                                @PathVariable("sourceId") long sourceId) {
        return ResourceUtils.getListById(request, response, sourceId, knowledgePointAppService::getNonAggregationRelationsByPoint);
    }

    //endregion

    /*@GetMapping("Subjects/{subjectId}/KnowledgePoints/{pointId}/TagNames")
    @Operation(summary = "通过学科知识点编号获取知识点关联标签名列表")
    @HandleResourceException
    public RestResponse<Collection<TagNameVO>> getTagNamesByPointId(@Context HttpServletRequest request, @Context HttpServletResponse response, @PathVariable("pointId") long pointId) {
        var result = knowledgePointAppService.getTagNamesByPoint(pointId);
        // var result = new ArrayList<TagNameVO>();
        return ResourceUtils.getOkResponse(request, response, result);
    }*/

}
